import React, { useEffect, useRef, useImperativeHandle } from 'react';
import { allGet } from '@/services/pc';
import { message } from 'antd';

const accept = [
  'wmv',
  'wm',
  'asf',
  'asx',
  'rm',
  'rmvb',
  'ra',
  'ram',
  'mpg',
  'mpeg',
  'mpe',
  'vob',
  'dat',
  'mov',
  '3gp',
  'mp4',
  'mp4v',
  'm4v',
  'mkv',
  'avi',
  'flv',
  'f4v',
];
const Index = React.forwardRef(({ onChange, children, payload, onSuccess }, ref) => {
  const uploadUrl = useRef(''); // demo 地址 "https://www.baijiayun.com/default/video_demo/getUploadUrl",  --》 https://e41544153.at.baijiayun.com/
  const inputRef = useRef();
  const uploader = useRef();
  const filelist = useRef([]);
  const update = () => {
    onChange?.(filelist.current);
  };
  const payloadRef = useRef(payload);
  const getBJYUploadUrl = async (data: any) => {
    const response = await allGet({
      params: {
        mod: 'baijiayun',
        do: 'getUploadUrl',
        version: 'pc1.0',
        file_name: data.videoName,
        classid: payloadRef.current.classid,
      },
    });
    if (response.success) {
      // uploadUrl.current = 'https://www.baijiayun.com/default/video_demo/getUploadUrl'
      // uploadUrl.current = response.data?.upload_url
      return {
        id: response.data.video_id,
        url: response.data?.upload_url,
      };
    }
  };
  const getBJYResumeUploadUrl = async (data) => {
    const response = await allGet({
      params: {
        mod: 'baijiayun',
        do: 'getResumeUploadUrl',
        version: 'pc1.0',
        video_id: data.uploadId,
      },
    });
    if (response.success) {
      // uploadUrl.current = 'https://www.baijiayun.com/default/video_demo/getUploadUrl'
      // uploadUrl.current = response.data?.upload_url
      return {
        fid: response.data.video_id,
        id: response.data.video_id,
        url: response.data.upload_url,
        uploaded: response.data.upload_size,
      };
    }
  };
  const getUploadUrl = (data: any) => {
    return $.ajax({
      url: uploadUrl.current,
      type: 'post',
      data: {
        file_name: data.videoName,
        definition: 1,
      },
      // headers: {
      //   'Content-Type': '',
      // },
    }).then(function (response) {
      const result = response.data;
      return {
        id: result.video_id,
        url: result.upload_url,
      };
    });
  };
  const getResumeUploadUrl = (data) => {
    // useChunk true 时必须实现此方法获取断点续传的上传地址
    // 此上传地址为 demo 调用，客户调用请使用 openapi getResumeUploadUrl 接口 https://dev.baijiayun.com/wiki/detail/4#-h5-9
    return $.ajax({
      url: 'https://www.baijiayun.com/default/video_demo/getResumeUploadUrl', // https://e41544153.at.baijiayun.com/
      type: 'post',
      data: {
        video_id: data.uploadId,
      },
    }).then(function (response) {
      const result = response.data;
      if (!result) {
        alert(response.msg);
        return;
      }
      return {
        fid: result.video_id,
        id: result.video_id,
        url: result.upload_url,
        uploaded: result.upload_size,
      };
    });
  };
  useEffect(() => {
    // getBJYUploadUrl()
    uploader.current = new BJY.VideoUploader({
      mainElement: $('#bjy-input-btn'),
      ignoreError: true,
      name: '',
      multiple: true,
      useChunk: true,
      // 接受的上传格式，如需支持音频上传，请传入音频格式到数组 [ 'mp3', 'wma', 'wav', 'mid', 'midd', 'kar', 'ogg', 'm4a', 'ra', 'ram', 'mod']
      accept: accept,
      needSaveChunkInfoToLocalStorage: true,
      getUploadUrl: getBJYUploadUrl,
      getResumeUploadUrl: getBJYResumeUploadUrl,
      onFileChange: function (files, file) {
        const hasSameFile = [];
        console.log(uploader.current?.currentFiles, 'uploader.currentFiles');
        const lasterFile =
          uploader.current?.currentFiles[uploader.current?.currentFiles.length - 1];
        const lasterSuffix = lasterFile.videoName.split('.');
        if (accept.indexOf(lasterSuffix[lasterSuffix.length - 1]) === -1) {
          // alert('文件格式不对')
          message.error('文件格式不对');
          return;
        }
        // 获取文件列表 使用uploader.autoUpload(file) 上传列表的每一个文件

        // 过滤出待上传的文件 0 等待上传 1 正在上传 2 上传完成 3 上传失败
        const filterCurrentFiles = uploader.current.currentFiles?.filter((item) => {
          const suffix = item.fileItem.file.name.split('.');
          return item.fileItem.status === 0 && accept.indexOf(suffix[suffix.length - 1]) !== -1;
        });
        console.log(filterCurrentFiles);

        // 用于uploader.autoUpload上传的数组
        const currentFiles = [];

        filterCurrentFiles.forEach((element, index) => {
          const nativeFile = element.fileItem.nativeFile;
          const name = nativeFile.name;

          // 这里同名的文件不允许上传
          // todo 0 等待上传 1 正在上传 2 上传完成 3 上传失败
          // 做的好点的话。给nativeFile加uploading / done / error的status状态，
          // 这边就可以判断 同名并且在status === uploading，的提示
          if (filelist.current.some((item) => item.name === name)) {
            hasSameFile.push(nativeFile);
            return;
          }

          // 通过对象引用关系， 这里做好给element.fileItem.nativeFile赋值一个uuid
          // 方便后面在onUploadProgress方法中，在react写法中，给filelist找到对应的item做进度更新
          nativeFile.uuid = Date.now() + '_' + index;
          nativeFile.percent = 0;

          // 允许上传个添加到currentFiles中
          currentFiles.push(element);

          // 用户更新react state的
          filelist.current.push(nativeFile);
        });
        if (hasSameFile.length > 0) {
          const arr = Array.from(
            // filter(item => !item.hasShowTips )
            // 这个是为了过滤出未弹窗提示的文件
            new Set(
              hasSameFile
                .filter((item) => !item.hasShowTips)
                .map((item) => {
                  // 标记下已经提示过了，下次可以过滤掉
                  item.hasShowTips = true;
                  return item.name;
                }),
            ),
          );
          if (arr.length > 0) {
            message.error(`以下文件重复上传:${arr.join('、')}`);
            // alert(`以下文件重复上传:${ arr.join('、')}`);
          }
        }

        if (!currentFiles.length) {
          return;
        }
        if (!uploader.current.validateFiles(currentFiles)) {
          uploader.current.reset();
          return;
        }
        currentFiles?.forEach((file) => {
          uploader.current.autoUpload(file);
        });
      },
      onUploadStart: function ({ fileItem }) {
        // onChange?.(data)
        const { chunk, file, nativeFile } = fileItem;
        filelist.current.forEach((current) => {
          if (current.uuid === nativeFile.uuid) {
            current.status = 'uploading';
            current.percent = Math.floor((chunk.uploaded / file.size) * 100);
          }
        });
        update();
        // 开始上传回调
      },
      onUploadProgress: function (data) {
        const uuid = data.fileItem.nativeFile.uuid;
      },
      onUploadSuccess: async function (data) {
        // 上传成功回调
        console.log('onUploadSuccess', data);
        console.log('onUploadSuccess responseText', data.responseText);
        const nativeFile = data.fileItem.nativeFile;
        const uuid = nativeFile.uuid;
        try {
          const response = JSON.parse(data.responseText);
          // 记录下fid，到时候传给活跃
          if (response.fid) {
            const params = {
              mod: 'baijiayun',
              do: 'add',
              version: 'pc1.0',
              classid: payloadRef.current.classid,
              vid: response.fid,
              filename: nativeFile.name,
              filesize: nativeFile.size,
              createlesson: payloadRef.current.createlesson,
            } as any;
            if (payloadRef.current.cid) {
              params.cid = payloadRef.current.cid;
            }
            const res = allGet({
              params,
              skipErrorHandler: true,
            });
          }
          filelist.current.forEach((current) => {
            if (current.uuid === uuid) {
              current.percent = 100;
              current.status = 'done';
              current.response = response;
            }
          });
          update();
          onSuccess?.();
        } catch (error) {
          console.log(error);
        }
      },
      onChunkUploadError: function (data) {
        // 这边可能也要处理
        // 但是没发复现，

        // 上传失败回调
        alert('上传错误，请重新上传');
      },
      onUploadError: function (data) {
        const uuid = data.fileItem.nativeFile.uuid;
        let response = {};
        try {
          response = JSON.parse(data.responseText);
        } catch (e) {}
        // 上传出错回调
        filelist.current.forEach((current) => {
          if (current.uuid === uuid) {
            current.current = 'error';
            current.response = response;
          }
        });
        update();
      },
      onUploadComplete: function (data) {
        // 上传完成回调
      },
      onError: function (data) {
        // todo 错误提示
        console.log(data);
        alert(data.content);
      },
    });
  }, []);

  const onClick = () => {
    inputRef.current?.click();
  };

  const stopFile = (file) => {
    const index = uploader.current?.currentFiles?.findIndex(
      (item) => item.fileItem?.nativeFile.uuid === file.uuid,
    );
    uploader.current?.stopFile(index);
    filelist.current = filelist.current?.map((item) => {
      if (file.uuid === item.uuid) {
        file.status = 'stop';
      }
      return item;
    });
    update();
  };
  const removeFile = (file) => {
    console.log(file);
    filelist.current = filelist.current?.filter((item) => item.uuid !== file.uuid);
    update();
  };
  const resumeFile = (file) => {
    const index = uploader.current?.currentFiles?.findIndex(
      (item) => item.fileItem?.nativeFile.uuid === file.uuid,
    );
    // 继续上传，开启分块上传后才能调用
    const data = uploader.current?.currentFiles?.[index];
    uploader.current?.resumeUpload(data);
  };
  const openSelect = ({ payload: _payload }) => {
    if (_payload) {
      payloadRef.current = _payload;
    }
    onClick();
  };

  /**
   * 供父组件调用
   */
  useImperativeHandle(ref, () => ({
    stopFile,
    resumeFile,
    removeFile,
    openSelect,
  }));

  return (
    <span>
      {/*'.avi', '.mp4', '.mov'*/}
      <input
        style={{ display: 'none' }}
        ref={inputRef}
        accept=".mp4,.avi,.mov"
        type="file"
        id="bjy-input-btn"
      />
      <span style={{ cursor: 'pointer' }} onClick={onClick}>
        {children}
      </span>
    </span>
  );
});

export default Index;
